import { Injectable } from '@nestjs/common';
import { CreatePurchaseDto } from './dto/create-purchase.dto';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository, DataSource } from 'typeorm';
import { Purchase, PurchaseGoods } from './entities/purchase.entity';
import { Admin } from 'src/admin/entities/admin.entity';
import { Supplier } from '../supplier/entities/supplier.entity';
import { dateNo, throwCustomException } from 'src/utils/fun';
@Injectable()
export class PurchaseService {
  constructor(
      @InjectRepository(Purchase)
      private readonly purchaseRepository: Repository<Purchase>,
      @InjectRepository(PurchaseGoods)
      private readonly purchaseGoodsRepository: Repository<Purchase>,
      private readonly dataSource: DataSource,
      ) {}
    async isPurchaseExists(where){
      const result = await this.purchaseRepository.findOne({where});
      return !!result
    }
  async create(createPurchaseDto: CreatePurchaseDto, tokenInfo) {
    const queryRunner = this.dataSource.createQueryRunner();
        await queryRunner.connect();
        await queryRunner.startTransaction();
        try {
          const saveData = {
            ...createPurchaseDto,
            createAdminId: tokenInfo.id,
          }
          // 如果 createSupplierDto.id 不为真（即新增操作），则添加 number 字段
          if (!createPurchaseDto.id) {
            saveData['code'] = 'CG' + dateNo() + Math.floor(Math.random() * 100).toString().padStart(3, '0')
          }
          const result = await queryRunner.manager.save(Purchase, {
            ...saveData
          })
          // 插入采购商品信息
          if (createPurchaseDto.goodItems && createPurchaseDto.goodItems.length > 0) {
            const purchaseGoodsList = createPurchaseDto.goodItems.map(good => ({
              purchaseId: result.id,
              goodsId: good.id,
              quantity: good.quantity,
              unitCost: good.unitCost,
              totalCost: good.quantity * good.unitCost
            }));
            await queryRunner.manager.save(PurchaseGoods, purchaseGoodsList);
          }
          await queryRunner.commitTransaction();
          return true;
        } catch (error) {
          await queryRunner.rollbackTransaction();
          throwCustomException(error.message);
        } finally {
          await queryRunner.release();
        }

  }

  async findAll(query) {
    try {
      const { page = 1, limit = 20, keyName = ''} = query
      const queryBuilder = await this.purchaseRepository
      .createQueryBuilder('purchase')
      .leftJoinAndSelect(Admin, 'admin', 'admin.id = purchase.createAdminId')
      .leftJoinAndSelect(Admin, 'applyAdmin', 'applyAdmin.id = purchase.applyAdminId') 
      .leftJoinAndSelect(Supplier, 'supplier', 'supplier.id = purchase.supplierId')
      .leftJoinAndSelect(PurchaseGoods, 'purchaseGoods', 'purchaseGoods.purchaseId = purchase.id')
      .select([
        'purchase.id AS id',
        'purchase.code AS code',
        'purchase.applyStatus AS applyStatus',
        'purchase.status AS status',
        'purchase.remark AS remark',
        'purchase.createTime AS createTime',
        'applyAdmin.nickname AS applyAdminName',
        'admin.nickname AS createAdminName',
        'supplier.name AS supplierName',
        'SUM(purchaseGoods.totalCost) AS totalCost'
      ])
      .groupBy('purchase.id')
      
      // 添加 categoryId 等值查询条件
      // if (categoryId) {
      //   queryBuilder.andWhere('goods.categoryId = :categoryId', { categoryId });
      // }

      // if (number) {
      //   queryBuilder.andWhere('goods.number = :number', { number });
      // }
      
      // 添加 keyName 对 name 字段的模糊查询条件
      if (keyName) {
        //queryBuilder.andWhere('supplier.name LIKE :keyName OR supplier.code LIKE :keyName', { keyName: `%${keyName}%` });
      }
      const purchase = await queryBuilder
        .offset(Number((page - 1) * limit))
        .limit(Number(limit))
        .getRawMany();
      const total = await queryBuilder
        .getCount();
      return [
        purchase, total
      ]
    } catch (error) {
      throwCustomException(error)
    }
  }

  async delete(id: string) {
      try {
        return await this.purchaseRepository.delete(id);
      } catch (error) {
        throwCustomException(error)
      }
    }
  
    async remove(id: string) {
      try {
        return await this.purchaseRepository.softDelete(id);
      } catch (error) {
        throwCustomException(error)
      }
    }
}
